<template>
  <div class="process-panel__container" style="width: 360px">
    <el-collapse v-model="activeTab">
      <el-collapse-item name="base">
        <div slot="title" class="panel-tab__title"><i class="el-icon-info" />
          <span v-if="bpmn.bpmnType === 'Process'">流程信息</span>
          <span v-else-if="bpmn.bpmnType !== 'SequenceFlow'">活动信息</span>
          <span v-else>流转信息</span>
        </div>
        <panel-base />
        <panel-process v-if="bpmn.bpmnType === 'Process'" />
        <panel-gateway v-else-if="bpmn.bpmnType === 'Gateway'"></panel-gateway>
        <panel-activity v-else-if="!['SequenceFlow','Process'].includes(bpmn.bpmnType)" />
      </el-collapse-item>
    </el-collapse>
  </div>
</template>
/**
* @description
* @author mao
* @time: 2021/8/12 1:22 下午
**/
<script>
import PanelBase from './panel/PanelBase'
import PanelProcess from "./panel/PanelProcess";
import PanelActivity from "./panel/PanelActivity";
import PanelGateway from "@/components/lab-bpmn/panel/PanelGateway";
export default {
  name: 'BpmnPanel',
  components: {PanelGateway, PanelActivity, PanelProcess, PanelBase },
  inject: {
    bpmn: {
      from: 'bpmn'
    }
  },
  provide() {
    return {
      setExtensions: this.setExtensions
    }
  },
  data() {
    return {
      activeTab: ['base'],
    }
  },
  created() {
    this.initModels()
  },
  methods: {
    initModels() {
      // 初始化 modeler 以及其他 moddle
      if (!this.bpmn.modeler) {
        // 避免加载时 流程图 并未加载完成
        this.timer = setTimeout(() => this.initModels(), 10)
        return
      }
      if (this.timer) {
        clearTimeout(this.timer)
      }
      const modeler = this.bpmn.modeler
      this.$set(this.bpmn, 'modeling', modeler.get('modeling'))
      this.$set(this.bpmn, 'moddle', modeler.get('moddle'))
      this.$set(this.bpmn, 'eventBus', modeler.get('eventBus'))
      this.$set(this.bpmn, 'bpmnFactory', modeler.get('bpmnFactory'))
      this.$set(this.bpmn, 'elementRegistry', modeler.get('elementRegistry'))
      this.$set(this.bpmn, 'replace', modeler.get('replace'))
      this.$set(this.bpmn, 'selection', modeler.get('selection'))
      this.getActiveElement()
    },
    getActiveElement() {
      // 初始第一个选中元素 bpmn:Process
      this.initFormOnChanged(null)
      this.bpmn.modeler.on('import.done', e => {
        this.initFormOnChanged(null)
      })
      // 监听选择事件，修改当前激活的元素以及表单
      this.bpmn.modeler.on('selection.changed', ({ newSelection }) => {
        this.initFormOnChanged(newSelection[0] || null)
      })
      this.bpmn.modeler.on('element.changed', ({ element }) => {
        // 保证 修改 "默认流转路径" 类似需要修改多个元素的事件发生的时候，更新表单的元素与原选中元素不一致。
        if (element && element.id === this.bpmn.bpmnId) {
          this.initFormOnChanged(element)
        }
      })
    },
    // 初始化数据
    initFormOnChanged(element) {
      let activatedElement = element
      if (!activatedElement) {
        activatedElement =
          this.bpmn.elementRegistry.find(el => el.type === 'bpmn:Process') ??
          this.bpmn.elementRegistry.find(el => el.type === 'bpmn:Collaboration')
      }
      if (!activatedElement) {
        return
      }
      this.bpmn.bpmnElement = activatedElement
      this.bpmn.bpmnId = activatedElement.id
      this.bpmn.bpmnType = activatedElement.type.split(':')[1] || ''
      if (this.bpmn.bpmnType === 'Process' && !activatedElement.businessObject.extensionElements){
        const { processDefId, processName, callCmd, processLabel, mainModel,mainPrimary,mainLabel,subModel,subPrimary,subLabel } = this.bpmn.bpmnData
        this.bpmn.bpmnData.id = processDefId
        this.bpmn.bpmnData.name = processName
        this.setExtensions({ callCmd, processLabel, mainModel,mainPrimary,mainLabel,subModel,subPrimary,subLabel })
      } else {
        this.bpmn.bpmnData = this.$Util.copy(this.bpmn.defData)
        this.$Util.copyAttr(this.$Util.copy(activatedElement.businessObject), this.bpmn.bpmnData)
        this.setExtentAttr(activatedElement.businessObject.extensionElements)
      }
    },
    // 设置bpmnData 值
    setExtentAttr(extension) {
      if (!extension) {
        return
      }
      const attr = extension.$attrs
      if (!this.$Util.isEmpty(attr)) {
        const { prop } = attr
        let modelData = this.bpmn.bpmnData
        if (prop) {
          this.$set(this.bpmn.bpmnData, prop, {})
          modelData = this.bpmn.bpmnData[prop]
        }
        const keys = Object.keys(attr)
        keys.forEach(key => {
          this.$set(modelData, key, attr[key])
        })
      }
      if (!this.$Util.isEmpty(extension.values)) {
        extension.values.forEach(value => {
          this.setExtentAttr(value)
        })
      }
    },
    /**
     * 扩展属性设置
     * @param config
     */
    setExtensions(config) {
      let { extensionElements } = this.bpmn.bpmnElement.businessObject
      if (!extensionElements) {
        // 属性配置
        const newProp = this.bpmn.moddle.create(`flowable:Property`, config)
        // 属性集合
        const props = this.bpmn.moddle.create(`flowable:Properties`, {
          values: [newProp]
        })
        // 扩展属性
        extensionElements = this.bpmn.moddle.create('bpmn:ExtensionElements', {
          values: [props]
        })
      } else {
        const props = extensionElements.values[0]
        const oldProp = props.values.find(item => item.$attrs.prop === config.prop)
        if (this.$Util.isEmpty(oldProp)) {
          props.values.push(this.bpmn.moddle.create(`flowable:Property`, config))
        } else {
          const keys = Object.keys(config)
          keys.forEach(key => {
            oldProp.$attrs[key] = config[key]
          })
        }
      }
      this.bpmn.modeling.updateProperties(this.bpmn.bpmnElement, {
        extensionElements: extensionElements
      })
    }
  }
}
</script>

<style scoped>

</style>
